package language;

public class LRational extends LType {
/*
    public final boolean isChar;
    private final long num, den;
    private final int exp;

    public LMagnitude(long num, long den, int exp, boolean isChar) {
        this.isChar = isChar;
        if (num != 0 || den != 0) {
            if (den < 0) {
                num = -num;
                den = -den;
            }
            while (num % 2 == 0 && den % 2 == 0) {
                num /= 2;
                den /= 2;
            }
            while (num % 3 == 0 && den % 3 == 0) {
                num /= 3;
                den /= 3;
            }
            while (num % 5 == 0 && den % 5 == 0) {
                num /= 5;
                den /= 5;
            }
            while (num % 7 == 0 && den % 7 == 0) {
                num /= 7;
                den /= 7;
            }
        }
        this.num = num;
        this.den = den;
        this.exp = exp;
    }

    public LMagnitude(LMagnitude that, boolean isChar) {
        this.num = that.num;
        this.den = that.den;
        this.exp = that.exp;
        this.isChar = isChar;
    }

    public LMagnitude multiply(LMagnitude that) {
        return new LMagnitude(
                this.num * that.num,
                this.den * that.den,
                this.exp + that.exp,
                isChar
        );
    }

    public LMagnitude divide(LMagnitude that) {
        return new LMagnitude(
                this.num * that.den,
                this.den * that.num,
                this.exp - that.exp,
                isChar
        );
    }

    public LMagnitude add(LMagnitude that) {
        long thisN = this.num;
        long thatN = that.num;
        long thisD = this.den;
        long thatD = that.den;
        int dif = this.exp - that.exp;
        while (dif > 0) {
            thisN *= 10;
            dif--;
        }
        while (dif < 0) {
            thatN *= 10;
            dif++;
        }
        return new LMagnitude(
                thisN * thatD + thisD * thatN,
                thisD * thatD,
                exp,
                isChar
        );
    }

    public LMagnitude subtract(LMagnitude m) {
        return add(new LMagnitude(-m.num, m.den, m.exp, m.isChar));
    }

    public LMagnitude power(LMagnitude that) {
        return new LNumber(Math.pow(this.toDouble(), that.toDouble()));
    }

    public LMagnitude modulo(LMagnitude that) {
        return new LNumber(this.toDouble() % that.toDouble());
    }

    @Override
    public LNumber asNumber() {
        return new LNumber(num, den, exp);
    }

    @Override
    public LCharacter asCharacter() {
        return new LCharacter((char) (num * pow10(exp) / den));
    }

    public double toDouble() {
        return num * pow10(exp) / den;
    }

    @Override
    public boolean toBoolean() {
        return num != 0;
    }

    @Override
    public String toString() {
        if (isChar) {
            return String.valueOf((char) toDouble());
        }
        if (num == 0 && den == 0) {
            return "NaN";
        }
        if (den == 0) {
            return "inifinity";
        }
        if (den == 1 && exp == 0) {
            return String.valueOf(num);
        }
        if (exp == 0) {
            if (num / den == num / (double) den) {
                return String.valueOf(num / den);
            }
            return String.valueOf(num / (double) den);
        }
        double d = num / (double) den;
        StringBuilder str = new StringBuilder();
        str.append(d);
        if (exp > 0 && str.indexOf(".") == -1) {
            for (int i = 0; i < exp; i++) {
                str.append('0');
            }
            return str.toString();
        }
        if (exp < 0) {
            int index = str.indexOf(".");
            if (index == -1) {
                index = str.length();
            } else {
                str.deleteCharAt(index);
            }
            int fromBack = str.length() - index;
            throw new UnsupportedOperationException("Not supported yet:\nBest guess:"
                                                    + str + " * 10^" + exp);
        }
        return str.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (!o.getClass().equals(getClass())) {
            return false;
        }
        LMagnitude that = (LMagnitude) o;
        if (this.isChar != that.isChar) {
            return false;
        }
        if (this.num == 0) {
            return that.num == 0;
        }
        if (that.num == 0) {
            return false;
        }
        double ratio = (this.num * (double) that.den) / (that.num * (double) this.den);
        return Math.abs(ratio - pow10(this.exp - that.exp)) < 0.01;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 23 * hash + (isChar ? 1 : 0);
        hash = 23 * hash + (int) (num ^ (num >>> 32));
        hash = 23 * hash + (int) (den ^ (den >>> 32));
        hash = 23 * hash + exp;
        return hash;
    }

    @Override
    public String toDebugString() {
        if (isChar) {
            return "'" + (char) toDouble() + "'";
        } else {
            if (den == 1 && exp == 0) {
                return String.valueOf(num);
            }
            if (den == 1) {
                return num + " * 10^" + exp;
            }
            if (exp == 0) {
                return num + " /" + den;
            }
            return num + " / " + den + " * 10^" + exp;
        }
    }

    public static double pow10(int i) {
        if (i > 0) {
            return pow10p(i - 1) / 10;
        } else if (i < 0) {
            return pow10n(i + 1) * 10;
        } else {
            return 1;
        }
    }

    public static double pow10p(int i) {
        if (i == 0) {
            return 1;
        }
        return 10 * pow10p(i - 1);
    }

    public static double pow10n(int i) {
        if (i == 0) {
            return 1;
        }
        return pow10n(i + 1) / 10;
    }*/
}
